package com.jintian.smart.kernel.oss.config;

import com.jintian.smart.kernel.autoconfigure.beetl.EnableBeetlMapper;
import com.jintian.smart.kernel.common.factory.YamlPropertySourceFactory;
import com.jintian.smart.kernel.oss.service.FileStorageCloudServiceImpl;
import com.jintian.smart.kernel.oss.service.FileStorageLocalServiceImpl;
import com.jintian.smart.kernel.oss.service.IFileStorageService;
import jakarta.annotation.Resource;
import lombok.Data;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.S3Configuration;

import java.net.URI;

/**
 * 文件上传 配置
 */
@Data
@Configuration
@EnableConfigurationProperties(OssProperty.class)
@PropertySource(factory = YamlPropertySourceFactory.class, value = "classpath:smart-oss.yml")
@EnableBeetlMapper(basePackages = {"com.jintian.smart.kernel.oss.mapper"}, sqlManager = "sqlManager", mapperSuffix = "Mapper")
public class OssConfig implements WebMvcConfigurer {
    private static final String HTTPS = "https://";

    private static final String HTTP = "http://";

    private static final String MODE_CLOUD = "cloud";

    private static final String MODE_LOCAL = "local";

    @Resource
    private OssProperty ossProperty;

    /**
     * 初始化 云oss client 配置
     *
     * @return
     */
    @Bean
    @ConditionalOnProperty(prefix = "file.storage", name = {"mode"}, havingValue = MODE_CLOUD)
    public S3Client initAmazonS3() {
        return S3Client.builder()
                .region(Region.AWS_GLOBAL)
                .endpointOverride(URI.create((ossProperty.getCloud().getUrlPrefix().startsWith(HTTPS) ? HTTPS : HTTP) + ossProperty.getCloud().getEndpoint()))
                .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(ossProperty.getCloud().getAccessKey(), ossProperty.getCloud().getSecretKey())))
                .serviceConfiguration(S3Configuration.builder()
                        .pathStyleAccessEnabled(true)
                        .chunkedEncodingEnabled(false)
                        .build())
                .build();
    }

    @Bean
    @ConditionalOnProperty(prefix = "smart.oss.storage", name = {"mode"}, havingValue = MODE_CLOUD)
    public IFileStorageService initCloudFileService() {
        return new FileStorageCloudServiceImpl();
    }

    @Bean
    @ConditionalOnProperty(prefix = "smart.oss.storage", name = {"mode"}, havingValue = MODE_LOCAL, matchIfMissing = true)
    public IFileStorageService initLocalFileService() {
        return new FileStorageLocalServiceImpl();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        if (MODE_LOCAL.equals(ossProperty.getMode())) {
            String path = ossProperty.getLocal().getUploadPath();
            path = path.endsWith("/") ? path : path + "/";
            registry.addResourceHandler(FileStorageLocalServiceImpl.UPLOAD_MAPPING + "/**").addResourceLocations("file:" + path);
        }
    }
}
